/**
 * 
 */
package edu.gtcfla.km.admin.appmodules.service.impl;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.vsg.biz.BusinessEntityFactory;
import org.vsg.biz.BusinessOperationException;
import org.vsg.biz.account.Role;
import org.vsg.biz.account.User;
import org.vsg.biz.account.repositories.RolePagingAndSortingRepo;
import org.vsg.biz.account.repositories.UserPagingAndSortingRepo;
import org.vsg.common.page.PageContentConverter;
import org.vsg.common.page.PageConverterTemplate;
import org.vsg.common.web.json.SelectItem;
import org.vsg.search.api.criterion.PaginationCriteria;
import org.vsg.search.api.page.PaginationException;

import edu.gtcfla.km.admin.appmodules.service.RoleService;
import edu.gtcfla.km.admin.appmodules.vo.RoleFormVO;
import edu.gtcfla.km.admin.appmodules.vo.RoleListedVO;
import edu.gtcfla.km.security.api.SubjectManager;

/**
 * @author Bill vison
 *
 */
public class RoleServiceImpl implements RoleService {

	private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);

	@Resource
	private RolePagingAndSortingRepo<Role, String> roleRepo;
	
	@Resource
	private UserPagingAndSortingRepo<User, String> userRepo;
	
	@Autowired(required=false)
	private SubjectManager subjectManager;
	
	
	private static BusinessEntityFactory entityFactory = BusinessEntityFactory.getInstance();	

	@Override
	public Page<RoleListedVO> pageRoles(PaginationCriteria criteria) throws BusinessOperationException,
			PaginationException {
		Page<Role>  pageOfRole =  roleRepo.findAll(criteria);
		
		
		PageContentConverter<RoleListedVO , Role> converter = new PageContentConverter<RoleListedVO , Role>() {

			@Override
			public RoleListedVO convert(Role source) {
				RoleListedVO item = new RoleListedVO(source);
			
				if ( source.getCreatedUserId() != null) {

					User oneUser = userRepo.findOne( source.getCreatedUserId() );
					item.setCreatedUser( oneUser.getName() );					
				}


				if ( source.getUpdatedUserId() != null) {
					User oneUser = userRepo.findOne( source.getUpdatedUserId() );
					item.setUpdatedUser( oneUser.getName() );					
				}
				
				if ( source.getOwnedUserId() != null) {
					User oneUser = userRepo.findOne( source.getOwnedUserId() );
					item.setOwnedUser( oneUser.getName() );					
				}

				
				return item;
			}
		};
		
		PageConverterTemplate<RoleListedVO, Role> pageTemplate = 
				new PageConverterTemplate<RoleListedVO,Role>( pageOfRole );
		Page<RoleListedVO> target = pageTemplate.convertContent(converter);
		return target;
	}

	@Override
	public void addRole(RoleFormVO role) throws BusinessOperationException {
		
		Role entity = role.getEntity();
		
		if (role.getCode() == null || role.getCode().trim().equals("")) {
			entity.setCode(null);
		}
		
		if (role.getTreemap() == null || role.getTreemap().trim().equals("")) {
			entity.setTreemap(null);
		}
		
		String currentUserId = subjectManager.getCurrentAccountId();
		entity.setCreatedUserId( currentUserId );
		entity.setOwnedUserId(  currentUserId );
		entity.setUpdatedUserId( currentUserId );
		
		Calendar cale = Calendar.getInstance();
		entity.setCreatedDate( cale.getTime() );
		entity.setUpdatedDate( cale.getTime() );

		
		roleRepo.save( entity );		
	}

	@Override
	public void addRoleWithParentRole(Role role, Serializable parentRolePK)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void deleteRole(Role role) throws BusinessOperationException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void deleteRolesDirectly(Set<RoleListedVO> roles) throws BusinessOperationException {
		
	}

	@Override
	public void updateRole(RoleFormVO role) throws BusinessOperationException {
		
		// --- update load and get data ---
		Role beforeChange = role.getEntity();
		
		Role entity = roleRepo.findOne( beforeChange.getId() );
		
		Set<String> ignorePropsSet = new LinkedHashSet<String>();
		ignorePropsSet.add("id" );
		ignorePropsSet.add( "createdDate"  );
		ignorePropsSet.add( "createdUserId"  );
		ignorePropsSet.add( "associatedActors"  );
		ignorePropsSet.add( "treemap"  );
		if (beforeChange.getRole() == null || beforeChange.getRole().equals("")) {
			ignorePropsSet.add("role");
		}
		if (beforeChange.getCode() == null || beforeChange.getCode().equals("")) {
			ignorePropsSet.add("code");
		}
	
		String[] ignoreProps = ignorePropsSet.toArray(new String[0] );
		
		BeanUtils.copyProperties( beforeChange , entity, ignoreProps);

		String currentUserId = subjectManager.getCurrentAccountId();
		entity.setOwnedUserId(  currentUserId );
		entity.setUpdatedUserId( currentUserId );
		
		Calendar cale = Calendar.getInstance();
		entity.setUpdatedDate( cale.getTime() );		
		
		roleRepo.update( entity );

		
	}

	@Override
	public void updateRoleWithParentRole(Role role, Serializable parentRolePK)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public RoleFormVO loadRole(Serializable pk) throws BusinessOperationException {
		
		Role role = roleRepo.findOne(pk.toString());
		
		RoleFormVO form = new RoleFormVO(role);
		
		// --- get record ---
		if ( role.getCreatedUserId()  != null) {
			User createUser = userRepo.findOne( role.getCreatedUserId() );
			form.setCreatedUser( createUser.getName() );		
		}
		
		if (role.getUpdatedUserId() != null) {
			User updateUser = userRepo.findOne( role.getUpdatedUserId());
			form.setUpdatedUser( updateUser.getName() );		
		}

		
		return form;
	}

	@Override
	public Role findParentRoleByRole(Role role) throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Collection<Role> findAvailableRolesOfTreeRoot() throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<RoleListedVO> findAllRolesForSelected() throws BusinessOperationException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<SelectItem> findAvailableRoles() throws BusinessOperationException {
		// --- find all avaialbe roles ---
		Iterable<Role>  availbItems = roleRepo.fildAllAvailable();
		
		Set<SelectItem> selItems = new LinkedHashSet<SelectItem>();
		for (Role role : availbItems) {
			SelectItem item = new SelectItem();
			item.setId( role.getId() );
			item.setName( role.getName() );
			
			selItems.add( item );
		}

		return selItems;
	}
	
	/**
	 * this method need to read system file
	 */
	@Override
	public Set<SelectItem> findAllSystemRoles()
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		Set<SelectItem> selItems = new LinkedHashSet<SelectItem>();
		SelectItem item = new SelectItem();
		item.setId( "admin");
		item.setName( "超级系统管理员" );
		selItems.add( item );		
		
		item = new SelectItem();
		item.setId( "business");
		item.setName( "业务系统管理员" );
		selItems.add( item );
		
		return selItems;
	}

	@Override
	public void deleteDirectlyByRoleIds(String[] receiveValues)
			throws BusinessOperationException {
		// TODO Auto-generated method stub
		for (String id : receiveValues) {
			Role role = entityFactory.create( Role.class );
			role.setId( id );

			roleRepo.deleteFully(role);

		}		
	}
	
	

	


	
	
}
